package cn.zsc.netdisk.controller;

import cn.zsc.netdisk.common.DownType;
import cn.zsc.netdisk.common.Paths;
import cn.zsc.netdisk.common.ZipType;
import cn.zsc.netdisk.exception.SharePasswordException;
import cn.zsc.netdisk.exception.ShareUrlException;
import cn.zsc.netdisk.response.Code;
import cn.zsc.netdisk.response.Result;
import cn.zsc.netdisk.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author ccying
 * @date 2021/2/20
 */
@RestController
@Slf4j
@RequestMapping("/file")
public class FileController {
    private FileService service;

    public FileController(FileService service) {
        this.service = service;
    }

    /**
     * 请求获取当前用户根目录存储文件
     * */
    @CrossOrigin
    @GetMapping("/getCurrentRootPathFiles")
    public Result getCurrentRootPathFiles() {
        System.out.println("*************************************************");
        log.info("请求获取当前用户根目录存储文件");
        cn.zsc.netdisk.pojo.File[] files;
        try {
            files = service.getCurrentRootPathFiles();
            return Result.success(files);
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求获取当前前台用户存储目录存储文件
     * @param path 给定前台当前抽象路径字符串
     * */
    @CrossOrigin
    @PostMapping("/getCurrentPathFiles")
    public Result getCurrentPathFiles(@RequestParam String path) {
        System.out.println("*************************************************");
        log.info(String.format("请求获取当前前台用户存储目录[%s]存储文件", path));
        try {
            cn.zsc.netdisk.pojo.File[] files = service.getCurrentPathFiles(path);
            return Result.success(files);
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求获取给定路径的文件夹名
     * @param path 给定抽象路径字符串
     * */
    @CrossOrigin
    @PostMapping("/getCurrentDirName")
    public Result getCurrentDirName(@RequestParam String path) {
        log.info("请求获取给定路径的文件夹名");
        List<String> names = this.service.getCurrentDirName(path);
        return Result.success(names);
    }

    /**
     * 请求传输图片文件
     * @param filename 文件名
     * @param type 传输类型
     * @param response http响应
     * */
    @GetMapping("/getImage/{filename}/{type}")
    @CrossOrigin
    public Result getImage(@PathVariable String filename, @PathVariable int type, HttpServletResponse response) {
        System.out.println("*************************************************");
        log.info("请求传输图片文件");
        try {
            service.getImage(filename, type, response);
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
        return null;
    }

    /**
     * 请求上传文件
     * @param files 要上传文件数组
     * */
    @CrossOrigin
    @PostMapping("/up")
    public Result up(@RequestParam MultipartFile[] files) {
        System.out.println("*************************************************");
        log.info("请求上传文件");
        try {
            this.service.saveFile(Paths.current_path, files);
            return Result.success();
        } catch (IOException e) {
            e.printStackTrace();
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求下载文件
     * @param request http请求
     * @param filename 给定要下载文件名
     * @param type 下载类型：0-下载存储文件，1-下载分享文件
     * */
    @CrossOrigin
    @GetMapping("/download/{filename}/{type}")
    public ResponseEntity<byte[]> download(HttpServletRequest request, @PathVariable String filename, @PathVariable int type) {
        System.out.println("*************************************************");
        log.info("请求下载文件");
        try {
            return this.service.download(request, filename, type);
        } catch (Exception e) {
            log.error(e.toString());
            return new ResponseEntity<byte[]>(e.getMessage().getBytes(), HttpStatus.EXPECTATION_FAILED);
        }
    }

    /**
     * 请求新建文件夹
     * @param path 给定要新建文件夹的前台抽象路径字符串
     * */
    @CrossOrigin
    @PostMapping("/mkdir")
    public Result createDirectory(@RequestParam String path) {
        System.out.println("*************************************************");
        log.info("请求新建文件夹");
        try {
            this.service.createDirectory(path);
            return Result.success();
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求移动文件
     * @param sources 给定要移动文件名数组
     * @param target 移动目标路径名
     * */
    @CrossOrigin
    @PostMapping("/move")
    public Result move(@RequestParam String[] sources, @RequestParam String target) {
        System.out.println("*************************************************");
        log.info("请求移动文件");
        try {
            this.service.move(sources, target);
            return Result.success();
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求删除存储文件
     * @param paths 给定要删除文件前台抽象路径字符串数组
     * */
    @CrossOrigin
    @PostMapping("/delete")
    public Result delete(@RequestParam String[] paths) {
        System.out.println("*************************************************");
        log.info("请求删除存储文件");
        try {
            this.service.deleteFile(paths);
            return Result.success();
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求分享文件
     * @param filename 给定要分享文件前台抽象路径字符串数组
     * */
    @CrossOrigin
    @GetMapping("/share/{filename}")
    public Result share(@PathVariable String filename) {
        System.out.println("*************************************************");
        log.info("请求分享文件");
        try {
            this.service.shareFile(filename);
            return Result.success();
        } catch (Exception e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求验证分享文件
     * @param url 分享链接url
     * @param password 分享链接密码
     * */
    @CrossOrigin
    @PostMapping("/share/verify")
    public Result verify(@RequestParam String url, @RequestParam int password) {
        System.out.println("*************************************************");
        log.info("请求验证分享文件");
        try {
            String name = this.service.verify(url, password);
            return Result.success(name);
        } catch (ShareUrlException e) {
            log.error(e.toString());
            return Result.fail(Code.SHARE_URL_NOT_EXIST);
        } catch (SharePasswordException e) {
            log.error(e.toString());
            return Result.fail(Code.SHARE_PASSWORD_ERROR);
        }
    }

    /**
     * 请求搜索文件名包含关键字的文件
     * @param key 关键字
     * @return 文件
     * */
    @CrossOrigin
    @GetMapping("/search/{key}")
    public Result search(@PathVariable String key) {
        System.out.println("*************************************************");
        log.info("请求搜索文件名包含关键字的文件");
        try {
            cn.zsc.netdisk.pojo.File[] files = this.service.searchFile(key);
            return Result.success(files);
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求重命名存储文件
     * @param source 原来文件名表示的前台抽象路径名
     * @param target 目标文件名表示的前台抽象路径名
     * */
    @CrossOrigin
    @PostMapping("/rename")
    public Result rename(@RequestParam String source, @RequestParam String target) {
        System.out.println("*************************************************");
        log.info("请求重命名存储文件");
        try {
            this.service.renameFile(source, target);
            return Result.success();
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }

    /**
     * 请求压缩文件
     * @param paths 给定要压缩文件抽象路径字符串
     * @param type 压缩打包类型，0-下载压缩，1-分享压缩
     * */
    @CrossOrigin
    @PostMapping("/zip/{type}")
    public Result toZip(@RequestParam String[] paths, @PathVariable int type) {
        System.out.println("*************************************************");
        log.info("请求压缩文件");
        try {
            String name = this.service.toZip(paths, type);
            return Result.success(name);
        } catch (IOException e) {
            log.error(e.toString());
            return Result.fail(Code.ERROR);
        }
    }
}
